#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Sep  6 17:55:04 2021

@author: Jessi
"""
import tkinter as tk, tkinter.ttk
import functools

try:
    import api, guitems
except ImportError:
    from . import api, guitems


class Config:
    def __init__(self):
        self.refresh()
    
    def refresh(self):
        path = api.get_config_paths("GUI")
        with open(path, "r", encoding="utf-8") as fp:
            self._Data = api.yaml.load(fp)
    def save(self):
        path = api.get_config_paths("GUI")
        with open(path, "w", encoding="utf-8") as fp:
            api.yaml.dump(self._Data, fp)
    
    def __getitem__(self, name):
        return self._Data[name]
    def __delitem__(self, name):
        "自动保存。"
        self._Data.pop(name)
        self.save()
    def __setitem__(self, name, value):
        "自动保存哦。"
        self._Data[name] = value
        self.save()

UiConfig = Config()

class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.set_basic()
        
        cfg = UiConfig["Timetable"]
        tb = guitems.Timetable(self.WorkWindow, self.manager, cfg)
        self.add_function("Timetable", tb)
    
    @property
    def ui_config(self):
        return UiConfig["MainWindow"]
    
    def set_basic(self):
        """设置变量值和基本控件。
        """
        self.manager = guitems.Manager()
        self.manager.add_frame("MainWindow", self)
        
        self.showing_frame = None
        self.showing_frame_name = None
        
        self.buttons_dict = {}
        self.buttons_actions = {}
        self.buttons_ordor = []
        self.function_frames = {}
        
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, minsize=90, weight=1)
        
        lmcfg = UiConfig["MainWindow"]["LeftMenu"]
        self.LeftMenu = LeftMenu = tk.Frame(self, **lmcfg["self cfg"])
        LeftMenu.pack(side="left", expand=0, fill="y")
        
        wwcfg = UiConfig["MainWindow"]["WorkWindow"]
        self.WorkWindow = WorkWindow = tk.Frame(self, **wwcfg["self cfg"])
        WorkWindow.pack(side="left", expand=1, fill="both")
        #为 LeftMenu & WorkWindow 这俩货挂载方式折腾了半天。
        #本来想使用 grid 方法，但发现拖拽主窗口时界面没有跟着拓展。
        #搜索后找到了 pack 拓展的方法。阅读后才发现 pack 其实不简单。
        #pack 的 fill 方法，指当分配的空间拓展时，是否拓展此控件。
        #        expand 方法，指当有可获得的空间时，是否扩展空间此控件被分配
        #的空间。某些情况下，空间不得不拓展，比如空件区域被拉大，且没有
        #其他控件允许主动扩展这些多余的空间。
    
    def show_frame(self, name):
        """关闭 WorkFrame 中正在展示的界面，展示 name 对应的界面。
        """
        frame = self.function_frames[name]
        if frame is not self.showing_frame:
            if self.showing_frame is not None:
                self.showing_frame.pack_forget()
            frame.pack(side="left", expand=1, fill="both")
            self.showing_frame = frame
            self.showing_frame_name = name
    
    def setup(self):
        "设置所有组件。启动窗口前请执行。"
        self.init_left_menu()
    
    def init_left_menu(self):
        """供 `setup` 调用。
初始化左侧菜单，包括设置按钮等。"""
        cfg_btn = self.ui_config["LeftMenu"]["btn"]
        def cmd(name):
            self.show_frame(name)
            act = self.buttons_actions[name]
            if act:
                act(self.manager)
        for row, name in enumerate(self.buttons_ordor):
            btn = tk.Button(self.LeftMenu,text=name, **cfg_btn["self cfg"])
            btn.config(command=functools.partial(cmd, name))
            self.buttons_dict[name] = btn
            btn.grid(row=row, column=0, sticky="ew", **cfg_btn["grid cfg"])
        #focus the first frame
        if len(self.buttons_ordor):
            self.show_frame(self.buttons_ordor[0])
    
    def add_function(self, name, frame, index=None, action=None):
        '''向应用添加功能。
添加后不会立即表现在图形窗口上，需执行 init_left_menu/setup（未启动窗口） 或
执行（窗口已启用） `fresh_function`。#TODO: fresh_function

name  : str LeftMenu 上按钮的文字，
frame : tk.Frame 按钮点击时 WorkWindow 显示的界面。应该为WorkFrame的子控件。
index : None or int 按键显示为第{index+1}项。
action: None or callable 当按键按下时，更改 WorkFrame 显示内容后执行的内容。
       执行的函数应接受 manage 一个值，即应用的管理者`manager`。

应用的“功能”如日程表、开始执行任务等大方向。
若添加自动化支持应用，请继承AutoFunc。#TODO: AutoFunc
        '''
        self.manager.add_frame(name, frame)#先向manager登记，因为有可能报错。
        self.buttons_dict[name] = None
        self.buttons_actions[name] = action
        self.function_frames[name] = frame
        
        index = len(self.buttons_ordor) if index is None else index
        self.buttons_ordor.insert(index, name)
    def remove_function(self, name=None, index=None):
        """移除已注册的功能。
        """#TODO
        